<script lang="ts" setup>
import type { Rule } from 'ant-design-vue/es/form';

import type { InfraConfigApi } from '#/api/infra/config';

import { onMounted, ref } from 'vue';

import { confirm, Page } from '@vben/common-ui';
import { IconifyIcon } from '@vben/icons';

import {
  Button,
  Card,
  Form,
  InputNumber,
  message,
  Space,
  Switch,
} from 'ant-design-vue';

import { listIgnoreTenant, updateBatchIgnoreTenant } from '#/api/infra/config';

// 定义安全配置类型
interface SecurityConfig {
  PASSWORD_ERROR_LOCK_COUNT?: InfraConfigApi.Config;
  PASSWORD_ERROR_LOCK_MINUTES?: InfraConfigApi.Config;
  PASSWORD_EXPIRATION_DAYS?: InfraConfigApi.Config;
  PASSWORD_EXPIRATION_WARNING_DAYS?: InfraConfigApi.Config;
  PASSWORD_REPETITION_TIMES?: InfraConfigApi.Config;
  PASSWORD_MIN_LENGTH?: InfraConfigApi.Config;
  PASSWORD_ALLOW_CONTAIN_USERNAME?: InfraConfigApi.Config;
  PASSWORD_REQUIRE_SYMBOLS?: InfraConfigApi.Config;
}
const form = ref<any>({
  PASSWORD_ERROR_LOCK_COUNT: 0,
  PASSWORD_ERROR_LOCK_MINUTES: 0,
  PASSWORD_EXPIRATION_DAYS: 0,
  PASSWORD_EXPIRATION_WARNING_DAYS: 0,
  PASSWORD_REPETITION_TIMES: 0,
  PASSWORD_MIN_LENGTH: 0,
  PASSWORD_ALLOW_CONTAIN_USERNAME: 0,
  PASSWORD_REQUIRE_SYMBOLS: 0,
});
const defaultform = ref<any>({
  PASSWORD_ERROR_LOCK_COUNT: 3,
  PASSWORD_ERROR_LOCK_MINUTES: 60,
  PASSWORD_EXPIRATION_DAYS: 0,
  PASSWORD_EXPIRATION_WARNING_DAYS: 0,
  PASSWORD_REPETITION_TIMES: 3,
  PASSWORD_MIN_LENGTH: 8,
  PASSWORD_ALLOW_CONTAIN_USERNAME: 0,
  PASSWORD_REQUIRE_SYMBOLS: 1,
});
const oldform = ref<any>({
  PASSWORD_ERROR_LOCK_COUNT: 3,
  PASSWORD_ERROR_LOCK_MINUTES: 60,
  PASSWORD_EXPIRATION_DAYS: 0,
  PASSWORD_EXPIRATION_WARNING_DAYS: 0,
  PASSWORD_REPETITION_TIMES: 3,
  PASSWORD_MIN_LENGTH: 8,
  PASSWORD_ALLOW_CONTAIN_USERNAME: 0,
  PASSWORD_REQUIRE_SYMBOLS: 1,
});
// 初始化安全配置
const securityConfig = ref<SecurityConfig>({
  PASSWORD_ERROR_LOCK_COUNT: {
    name: '密码错误锁定阈值',
    remark: '连续登录失败次数达到该值将锁定账号（0-10次，0表示禁用锁定）',
  } as InfraConfigApi.Config,
  PASSWORD_ERROR_LOCK_MINUTES: {
    name: '账号锁定时长（分钟）',
    remark: '账号锁定后自动解锁的时间（1-1440分钟，即24小时）',
  } as InfraConfigApi.Config,
  PASSWORD_EXPIRATION_DAYS: {
    name: '密码有效期（天）',
    remark: '密码强制修改周期（0-999天，0表示永不过期）',
  } as InfraConfigApi.Config,
  PASSWORD_EXPIRATION_WARNING_DAYS: {
    name: '密码到期提醒时间（天）',
    remark: '密码过期前的提前提醒天数（0表示不提醒）',
  } as InfraConfigApi.Config,
  PASSWORD_REPETITION_TIMES: {
    name: '历史密码重复校验次数',
    remark: '禁止使用最近 N 次的历史密码（3-32次）',
  } as InfraConfigApi.Config,
  PASSWORD_MIN_LENGTH: {
    name: '密码最小长度',
    remark: '密码最小字符长度要求（8-32个字符）',
  } as InfraConfigApi.Config,
  PASSWORD_ALLOW_CONTAIN_USERNAME: {
    name: '是否允许密码包含用户名',
    remark: '是否允许密码包含正序或倒序的用户名字符',
  } as InfraConfigApi.Config,
  PASSWORD_REQUIRE_SYMBOLS: {
    name: '是否要求密码必须包含特殊字符',
    remark: '是否要求密码必须包含特殊字符（如：!@#$%）',
  } as InfraConfigApi.Config,
});

const rules: Record<string, Rule[]> = {
  PASSWORD_ERROR_LOCK_COUNT: [{ required: true, message: '请输入值' }],
  PASSWORD_ERROR_LOCK_MINUTES: [{ required: true, message: '请输入值' }],
  PASSWORD_EXPIRATION_DAYS: [{ required: true, message: '请输入值' }],
  PASSWORD_EXPIRATION_WARNING_DAYS: [
    { required: true, message: '请输入值' },
    {
      validator: (_rule: Rule, value: string) => {
        return form.value.PASSWORD_EXPIRATION_DAYS > 0 &&
          value >= form.value.PASSWORD_EXPIRATION_DAYS
          ? Promise.reject(new Error('密码到期提醒时间应小于密码有效期'))
          : Promise.resolve();
      },
      trigger: 'change',
    },
  ],
  PASSWORD_REPETITION_TIMES: [{ required: true, message: '请输入值' }],
  PASSWORD_MIN_LENGTH: [{ required: true, message: '请输入值' }],
};
const loading = ref<boolean>(false);
const formRef = ref();
const isUpdate = ref(false);
const queryForm = {
  category: 'PASSWORD',
};
// 加载安全配置
const getData = async () => {
  try {
    loading.value = true;
    const data = await listIgnoreTenant(queryForm);
    if (data && data.length > 0) {
      const configList = data.reduce(
        (obj: SecurityConfig, option: InfraConfigApi.Config) => {
          obj[option.key] = { ...option, value: Number.parseInt(option.value) };
          form.value[option.key] = Number.parseInt(option.value);
          oldform.value[option.key] = Number.parseInt(option.value);
          return obj;
        },
        {},
      );
      // 根据key 和原有的configList 合并
      securityConfig.value = { ...securityConfig.value, ...configList };
    }
    loading.value = false;
  } catch (error) {
    message.error('加载安全配置失败');
    console.error('Failed to load security config:', error);
  }
};

// 保存安全配置
const handleSave = async () => {
  const valid = await formRef.value.validate().catch(() => false);
  if (!valid) return false;
  try {
    await updateBatchIgnoreTenant(
      Object.entries(form.value).map(([key, value]) => {
        return {
          id: securityConfig.value[key]?.id,
          key,
          value,
          name: securityConfig.value[key]?.name,
          visible: false,
          category: 'PASSWORD',
          type: 1,
          remark: securityConfig.value[key]?.remark,
        } as InfraConfigApi.Config;
      }),
    );
    await getData();
    message.success('保存成功');
  } catch (error) {
    message.error('保存失败');
    console.error('Failed to save security config:', error);
  }
};

const onResetValue = () => {
  confirm('确认恢复安全配置为默认值吗？')
    .then(async () => {
      await updateBatchIgnoreTenant(
        Object.entries(defaultform.value).map(([key, value]) => {
          return {
            id: securityConfig.value[key]?.id,
            key,
            value,
            name: securityConfig.value[key]?.name,
            visible: false,
            category: 'PASSWORD',
            type: 1,
            remark: securityConfig.value[key]?.remark,
          } as InfraConfigApi.Config;
        }),
      );

      message.success({
        content: '恢复成功',
        key: 'action_key_msg_success',
      });
      await getData();
    })
    .catch(() => {});
};
// 修改
const onUpdate = () => {
  isUpdate.value = true;
};

// 取消
const handleCancel = () => {
  form.value = Object.assign({}, oldform.value);
  isUpdate.value = false;
};
// 初始加载配置
onMounted(() => {
  getData();
});
</script>

<template>
  <Page auto-content-height>
    <Card title="安全配置">
      <Form
        ref="formRef"
        :loading="loading"
        :rules="rules"
        :model="form"
        :disabled="!isUpdate"
        label-align="left"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 16 }"
      >
        <Form.Item
          :label="securityConfig.PASSWORD_ERROR_LOCK_COUNT.name"
          name="PASSWORD_ERROR_LOCK_COUNT"
          :help="securityConfig.PASSWORD_ERROR_LOCK_COUNT.remark"
        >
          <InputNumber
            v-model:value="form.PASSWORD_ERROR_LOCK_COUNT"
            :min="0"
            :max="10"
          >
            <template #addonAfter> 次 </template>
          </InputNumber>
        </Form.Item>

        <Form.Item
          :label="securityConfig.PASSWORD_ERROR_LOCK_MINUTES.name"
          name="PASSWORD_ERROR_LOCK_MINUTES"
          :help="securityConfig.PASSWORD_ERROR_LOCK_MINUTES.remark"
        >
          <InputNumber
            v-model:value="form.PASSWORD_ERROR_LOCK_MINUTES"
            :min="1"
            :max="1440"
          >
            <template #addonAfter> 分钟 </template>
          </InputNumber>
        </Form.Item>

        <Form.Item
          :label="securityConfig.PASSWORD_EXPIRATION_DAYS.name"
          name="PASSWORD_EXPIRATION_DAYS"
          :help="securityConfig.PASSWORD_EXPIRATION_DAYS.remark"
        >
          <InputNumber
            v-model:value="form.PASSWORD_EXPIRATION_DAYS"
            :min="0"
            :max="999"
          >
            <template #addonAfter> 天 </template>
          </InputNumber>
        </Form.Item>

        <Form.Item
          :label="securityConfig.PASSWORD_EXPIRATION_WARNING_DAYS.name"
          name="PASSWORD_EXPIRATION_WARNING_DAYS"
          :help="securityConfig.PASSWORD_EXPIRATION_WARNING_DAYS.remark"
        >
          <InputNumber
            v-model:value="form.PASSWORD_EXPIRATION_WARNING_DAYS"
            :min="0"
            :max="30"
          >
            <template #addonAfter> 天 </template>
          </InputNumber>
        </Form.Item>

        <Form.Item
          :label="securityConfig.PASSWORD_REPETITION_TIMES.name"
          name="PASSWORD_REPETITION_TIMES"
          :help="securityConfig.PASSWORD_REPETITION_TIMES.remark"
        >
          <InputNumber
            v-model:value="form.PASSWORD_REPETITION_TIMES"
            :min="3"
            :max="32"
          >
            <template #addonAfter> 次 </template>
          </InputNumber>
        </Form.Item>

        <Form.Item
          :label="securityConfig.PASSWORD_MIN_LENGTH.name"
          name="PASSWORD_MIN_LENGTH"
          :help="securityConfig.PASSWORD_MIN_LENGTH.remark"
        >
          <InputNumber
            v-model:value="form.PASSWORD_MIN_LENGTH"
            :min="8"
            :max="32"
          >
            <template #addonAfter> 字符 </template>
          </InputNumber>
        </Form.Item>

        <Form.Item
          :label="securityConfig.PASSWORD_ALLOW_CONTAIN_USERNAME.name"
          name="PASSWORD_ALLOW_CONTAIN_USERNAME"
          :help="securityConfig.PASSWORD_ALLOW_CONTAIN_USERNAME.remark"
        >
          <Switch
            v-model:checked="form.PASSWORD_ALLOW_CONTAIN_USERNAME"
            checked-children="是"
            un-checked-children="否"
            :checked-value="1"
            :un-checked-value="0"
          />
        </Form.Item>

        <Form.Item
          :label="securityConfig.PASSWORD_REQUIRE_SYMBOLS.name"
          name="PASSWORD_REQUIRE_SYMBOLS"
          :help="securityConfig.PASSWORD_REQUIRE_SYMBOLS.remark"
        >
          <Switch
            v-model:checked="form.PASSWORD_REQUIRE_SYMBOLS"
            checked-children="是"
            un-checked-children="否"
            :checked-value="1"
            :un-checked-value="0"
          />
        </Form.Item>
        <Space style="margin-bottom: 16px">
          <Button
            type="primary"
            @click="onUpdate"
            v-if="!isUpdate"
            :disabled="false"
          >
            <IconifyIcon icon="lucide:edit" /> 修改
          </Button>
          <Button
            @click="onResetValue"
            style="margin-left: 20px"
            :disabled="false"
            v-if="!isUpdate"
          >
            <IconifyIcon icon="lucide:rotate-ccw" /> 恢复默认
          </Button>
          <Button
            @click="handleSave"
            :disabled="false"
            v-if="isUpdate"
            type="primary"
          >
            <IconifyIcon icon="lucide:save" /> 保存
          </Button>
          <Button
            @click="handleCancel"
            style="margin-left: 20px"
            :disabled="false"
            v-if="isUpdate"
          >
            <IconifyIcon icon="lucide:shield-close" /> 取消
          </Button>
        </Space>
      </Form>
    </Card>
  </Page>
</template>

<style lang="less" scoped>
.form-hint {
  margin-top: 4px;
  font-size: 12px;
  color: #999;
}
</style>
